package com.example.attack.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.attack.listener.enums.AttackListenerEnum;
import com.example.attack.mapper.ElCharacterMapper;
import com.example.attack.model.ElCharacter;
import com.example.attack.service.ElCharacterService;
import com.example.attack.utils.Event;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Slf4j
@Service
public class ElCharacterServiceImpl extends ServiceImpl<ElCharacterMapper, ElCharacter> implements ElCharacterService {

    @Autowired
    private ApplicationEventPublisher publisher;

    @Override
    @Transactional
    public ElCharacter commonAttack(Integer id) {
        ElCharacter elCharacter = attackElCharacter(id);
        publisher.publishEvent(new Event(AttackListenerEnum.COMMON_ATTACK, elCharacter));
        return elCharacter;
    }

    @Override
    @Transactional
    public ElCharacter physicalAttack(Integer id) {
        ElCharacter elCharacter = attackElCharacter(id);
        publisher.publishEvent(new Event(AttackListenerEnum.PHYSICAL_ATTACK, elCharacter));
        return elCharacter;
    }

    @Override
    public void mockSelectDelayCommon(Integer id) throws InterruptedException {
        ElCharacter elCharacter = this.getById(id);
        System.out.println("mockSelectDelayCommon" + elCharacter.getHp());
//        Thread.sleep(5000);
        elCharacter = this.getById(id);
        elCharacter = this.getOne(new LambdaQueryWrapper<ElCharacter>().eq(ElCharacter::getName, "和尚"));
        System.out.println("mockSelectDelayCommon [delay]" + elCharacter.getHp());
    }

    @Override
    @Transactional
    public void mockSelectDelayTransactional(Integer id) throws InterruptedException {
        ElCharacter elCharacter = this.getById(id);
        System.out.println("mockSelectDelayTransactional" + elCharacter.getHp());
        Thread.sleep(5000);
//        elCharacter = this.getById(id);
        elCharacter = this.getOne(new LambdaQueryWrapper<ElCharacter>().eq(ElCharacter::getName, "和尚"));
        System.out.println("mockSelectDelayTransactional [delay]" + elCharacter.getHp());
    }

    @Override
    public void updateElCharacter(Integer id) {
        this.update(new LambdaUpdateWrapper<ElCharacter>().set(ElCharacter::getHp, 66).eq(ElCharacter::getId, id));
    }

    private ElCharacter attackElCharacter(Integer id) {
        ElCharacter elCharacter = this.getById(id);
        if (elCharacter.getAc() > 0) {
            elCharacter.setAc(elCharacter.getAc() - 5);
        } else {
            elCharacter.setHp(elCharacter.getHp() - 5);
        }
        this.updateById(elCharacter);
        return elCharacter;
    }
}
